﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO; 

using DupeKill.Core;
using DupeKill.Core.IO;
using DupeKill.Core.Discovery; 

namespace DupeKill.UnitTests.Helpers
{
    internal class TestCaseFileSystemGateway : IFileSystemGateway 
    {
        private class Record
        {
            public Record(string path, byte [] data)
            {
                Path = path;
                Data = data; 
            }

            public string Path { get; private set; }
            public byte[] Data { get; private set; }
        }

        private List<Record> records = new List<Record>(); 

        public void Add(string path, string data)
        {
            records.Add(new Record(path, Encoding.Default.GetBytes(data))); 
        }

        public IFileIterator CreateIterator()
        {
            return new Iterator(records); 
        }

        #region IFileSystemGateway Member

        public Stream OpenFile(string path)
        {
            Record rc = records.Where(x => x.Path == path).FirstOrDefault();
            if (rc == null)
                throw new ArgumentNullException();

            return new MemoryStream(rc.Data); 
        }

        #endregion

        private class Iterator : IFileIterator 
        {
            private List<Record> records;
            private int current = -1; 
            public Iterator(List<Record> records)
            {
                this.records = records; 
            }

            #region IFileIterator Member

            public string Directory
            {
                get { return Path.GetDirectoryName(FullPath); }
            }

            public string FileName
            {
                get {return Path.GetFileName(FullPath); }
            }

            public string FullPath
            {
                get { return GetCurrentOrThrow().Path; }
            }

            public long Length
            {
                get { return GetCurrentOrThrow().Data.Length; }
            }

            public void Reset()
            {
                current = -1; 
            }

            public bool Next()
            {
                current++;

                return current < records.Count; 
            }

            #endregion

            #region IDisposable Member

            public void Dispose()
            {
              
            }

            #endregion

            private Record GetCurrentOrThrow()
            {
                return records[current]; 
            }
        }

        public static TestCaseFileSystemGateway Create(string[] fileNames, string[] contents)
        {
            TestCaseFileSystemGateway fileSystem = new TestCaseFileSystemGateway();

            for (int i = 0; i < fileNames.Length; i++)
            {
                fileSystem.Add(fileNames[i], contents[i]);
            }

            return fileSystem; 
        }
    }
}
